package com.zhenwei.zscm.common.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.zhenwei.zscm.common.excel.model.ExcelBaseModel;
import com.zhenwei.zscm.common.excel.model.ExcelHeadModel;
import com.zhenwei.zscm.common.excel.model.ExcelMergeModel;

import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

public class DefaultListener<T extends ExcelBaseModel> implements ReadListener<T> {
    private Consumer<T> consumer;
    private Consumer<ExcelMergeModel> mergeModelConsumer;
    private Consumer<ExcelHeadModel> headModelConsumer;
    /**
     * 监听读取数据
     * @param consumer 回调
     */
    public void listenRead(Consumer<T> consumer) {
        this.consumer  = consumer;
    }
    /**
     * 监听读取合并数据
     * @param mergeModelConsumer 回调
     */
    public void listenReadMerge(Consumer<ExcelMergeModel> mergeModelConsumer) {
        this.mergeModelConsumer = mergeModelConsumer;
    }
    /**
     * 监听处理表头
     * @param headModelConsumer 回调
     */
    public void listenReadHead(Consumer<ExcelHeadModel> headModelConsumer) {
        this.headModelConsumer = headModelConsumer;
    }
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        ReadListener.super.onException(exception, context);
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        headMap.forEach( (k,v)->{
            ExcelHeadModel head = new ExcelHeadModel();
            head.setRowIndex(v.getRowIndex());
            head.setColumnIndex(v.getColumnIndex());
            head.setColumnName(v.getStringValue());
            headModelConsumer.accept(head);
        });
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
        data.setRowNum(context.readRowHolder().getRowIndex());
        consumer.accept(data);
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        if (Objects.requireNonNull(extra.getType()) == CellExtraTypeEnum.MERGE) {
            var merge = new ExcelMergeModel();
            merge.setMergeFromRowNum(extra.getFirstRowIndex());
            merge.setMergeFromColumnNum(extra.getFirstColumnIndex());
            merge.setMergeToRowNum(extra.getLastRowIndex());
            merge.setMergeToColNum(extra.getLastColumnIndex());
            mergeModelConsumer.accept(merge);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return ReadListener.super.hasNext(context);
    }
}
